#!/usr/bin/env python3
"""
程序稳定性监控工具
"""

import sys
import time
import threading
import psutil
import os
from PySide6.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QWidget, 
                              QLabel, QPushButton, QTextEdit, QHBoxLayout)
from PySide6.QtCore import QTimer, QThread, Signal

class StabilityMonitor(QThread):
    """稳定性监控线程"""
    status_update = Signal(str)
    
    def __init__(self):
        super().__init__()
        self.monitoring = False
        self.process = psutil.Process()
        self.start_time = time.time()
        self.initial_memory = self.process.memory_info().rss / 1024 / 1024  # MB
        
    def run(self):
        """监控循环"""
        while self.monitoring:
            try:
                # 获取当前状态
                current_time = time.time()
                runtime = current_time - self.start_time
                
                # 内存使用
                memory_info = self.process.memory_info()
                current_memory = memory_info.rss / 1024 / 1024  # MB
                memory_growth = current_memory - self.initial_memory
                
                # CPU使用率
                cpu_percent = self.process.cpu_percent()
                
                # 线程数量
                thread_count = self.process.num_threads()
                
                # 文件句柄数量（Windows上可能不可用）
                try:
                    file_handles = self.process.num_handles() if hasattr(self.process, 'num_handles') else 0
                except:
                    file_handles = 0
                
                # 生成状态报告
                status = f"""运行时间: {runtime:.1f}秒
内存使用: {current_memory:.1f}MB (增长: {memory_growth:+.1f}MB)
CPU使用率: {cpu_percent:.1f}%
线程数量: {thread_count}
文件句柄: {file_handles}
"""
                
                self.status_update.emit(status)
                
                # 检查异常情况
                if memory_growth > 100:  # 内存增长超过100MB
                    self.status_update.emit("⚠️ 警告: 内存使用增长过多，可能存在内存泄漏")
                
                if thread_count > 20:  # 线程数量过多
                    self.status_update.emit("⚠️ 警告: 线程数量过多，可能存在线程泄漏")
                
                time.sleep(2)  # 每2秒更新一次
                
            except Exception as e:
                self.status_update.emit(f"❌ 监控错误: {e}")
                break
    
    def start_monitoring(self):
        """开始监控"""
        self.monitoring = True
        self.start()
    
    def stop_monitoring(self):
        """停止监控"""
        self.monitoring = False

class StabilityMonitorWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("程序稳定性监控")
        self.setGeometry(200, 200, 500, 400)
        
        # 设置UI
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        layout = QVBoxLayout(central_widget)
        
        # 标题
        title_label = QLabel("程序稳定性监控")
        title_label.setStyleSheet("font-size: 16px; font-weight: bold;")
        layout.addWidget(title_label)
        
        # 控制按钮
        button_layout = QHBoxLayout()
        
        self.start_btn = QPushButton("开始监控")
        self.start_btn.clicked.connect(self.start_monitoring)
        button_layout.addWidget(self.start_btn)
        
        self.stop_btn = QPushButton("停止监控")
        self.stop_btn.clicked.connect(self.stop_monitoring)
        self.stop_btn.setEnabled(False)
        button_layout.addWidget(self.stop_btn)
        
        self.clear_btn = QPushButton("清空日志")
        self.clear_btn.clicked.connect(self.clear_log)
        button_layout.addWidget(self.clear_btn)
        
        layout.addLayout(button_layout)
        
        # 状态显示
        self.status_label = QLabel("准备开始监控...")
        layout.addWidget(self.status_label)
        
        # 日志显示
        self.log_text = QTextEdit()
        self.log_text.setReadOnly(True)
        layout.addWidget(self.log_text)
        
        # 监控器
        self.monitor = StabilityMonitor()
        self.monitor.status_update.connect(self.update_status)
        
        # 定时器用于更新UI
        self.update_timer = QTimer()
        self.update_timer.timeout.connect(self.update_display)
        
    def start_monitoring(self):
        """开始监控"""
        self.log("🚀 开始稳定性监控...")
        self.monitor.start_monitoring()
        self.update_timer.start(2000)  # 每2秒更新UI
        
        self.start_btn.setEnabled(False)
        self.stop_btn.setEnabled(True)
        self.status_label.setText("监控进行中...")
        
    def stop_monitoring(self):
        """停止监控"""
        self.log("🛑 停止稳定性监控")
        self.monitor.stop_monitoring()
        self.update_timer.stop()
        
        self.start_btn.setEnabled(True)
        self.stop_btn.setEnabled(False)
        self.status_label.setText("监控已停止")
        
    def update_status(self, status):
        """更新状态"""
        timestamp = time.strftime("%H:%M:%S")
        self.log(f"[{timestamp}] {status}")
        
    def update_display(self):
        """更新显示"""
        if self.monitor.monitoring:
            runtime = time.time() - self.monitor.start_time
            self.status_label.setText(f"监控进行中... 运行时间: {runtime:.0f}秒")
    
    def clear_log(self):
        """清空日志"""
        self.log_text.clear()
        
    def log(self, message):
        """添加日志"""
        self.log_text.append(message)
        print(message)
        
    def closeEvent(self, event):
        """窗口关闭时清理"""
        if self.monitor.monitoring:
            self.stop_monitoring()
        super().closeEvent(event)

def main():
    app = QApplication(sys.argv)
    
    print("📊 程序稳定性监控工具")
    print("=" * 50)
    print("此工具将监控主程序的资源使用情况")
    print()
    print("监控指标:")
    print("• 运行时间")
    print("• 内存使用和增长")
    print("• CPU使用率")
    print("• 线程数量")
    print("• 文件句柄数量")
    print()
    print("使用方法:")
    print("1. 先启动主程序 (python main.py)")
    print("2. 启动此监控工具")
    print("3. 点击'开始监控'")
    print("4. 在主程序中进行各种操作")
    print("5. 观察资源使用变化")
    print()
    print("异常指标:")
    print("• 内存持续增长 > 100MB")
    print("• 线程数量 > 20")
    print("• CPU使用率持续 > 50%")
    print("=" * 50)
    
    window = StabilityMonitorWindow()
    window.show()
    
    sys.exit(app.exec())

if __name__ == "__main__":
    main()
